Imports VB = Microsoft.VisualBasic

''' <summary>
''' Class for all classes to read DSS data
''' </summary>
Public Class clsDataDSS
    Inherits clsData

    Private mDescription As String
    Private mUnits As String
    Private mDate_Time() As Date
    Private mResult() As Single

    'local variable(s) to hold property value(s)
    Const PartA As Short = 1
    Const PartB As Short = 2
    Const PartC As Short = 3
    Const PartD As Short = 4
    Const PartE As Short = 5
    Const PartF As Short = 6

    Private Sub getData(ByVal DataPath As String)
        Dim CName, MessageFile As String
        Dim ISTAT As Integer

        Dim IFLTAB(600) As Integer
        Dim lngStatus As Integer
        Dim StartDate As Date
        Dim Increment As String
        Dim TimeIncrement As Single
        Dim NotRTS As Boolean
        Dim ErrMsg As String = ""

        CName = mFilename

        MessageFile = CName & ".msg"
        ISTAT = FORTRANOPENFILE(MessageFile, Len(MessageFile), 10)
        If ISTAT <> 0 Then Throw New IO.FileNotFoundException("Unable to create message file: " & Trim(MessageFile) & "; operation aborted.")

        ZSET("MUNIT", 5, " ", 1, 10)

        ZOPEN(IFLTAB(1), CName, Len(CName), ISTAT)
        Select Case ISTAT
            Case 0 'successful
            Case -1 : ErrMsg = "Unable to create DSS file"
            Case -2 : ErrMsg = "Unable to connect to DSS file"
            Case -3 : ErrMsg = "Incompatible DSS version"
            Case -10 : ErrMsg = "No DSS file name was provided"
            Case Is > 0 : ErrMsg = "Error executing FORTRAN open statement"
        End Select
        If ISTAT <> 0 Then Throw New IO.IOException(ErrMsg & ": " & Trim(CName) & "; operation aborted.")

        'see if selected dataset is a time series
        Dim lngLExist, lngNSize, lngDType As Integer
        Dim CPath As String
        Dim strDType As New VB6.FixedLengthString(20)

        mUnits = ""
        NotRTS = False

        Dim strCDate As New VB6.FixedLengthString(12)
        Dim strCTime As New VB6.FixedLengthString(4)
        Dim lngIOFSET As Integer
        Dim lngNVals As Integer
        Dim i As Integer
        Dim strCUnits As New VB6.FixedLengthString(8)
        Dim strCType As New VB6.FixedLengthString(8)
        CPath = DataPath

        ZDTYPE(IFLTAB(1), CPath, Len(CPath), lngNSize, lngLExist, strDType.Value, Len(strDType.Value), lngDType)

        If Trim(strDType.Value) <> "RTS" Then

            NotRTS = True

        Else

            'break apart path to get starting date in position E

            strCDate.Value = CPath.Split("/")(PartD)
            strCTime.Value = "0000"
            lngNVals = lngNSize
            ReDim mResult(lngNVals - 1)

            '
            '   Call DSS function to retrieve regular time series
            ZRRTS(IFLTAB(1), CPath, Len(CPath), strCDate.Value, Len(strCDate.Value), strCTime.Value, Len(strCTime.Value), lngNVals, mResult(0), strCUnits.Value, Len(strCUnits.Value), strCType.Value, Len(strCType.Value), lngIOFSET, ISTAT)

            Select Case ISTAT
                Case 11 : ErrMsg = "No values were requested"
                Case 12 : ErrMsg = "Non-standard time interval in 'E' part of pathname"
                Case 15 : ErrMsg = "Starting date or time not recognized"
                Case 20 : ErrMsg = "Data not recognized as regular-interval time series"
                Case 24 : ErrMsg = "Pathname given does not meet regular-interval time series conventions"
                Case 53 : ErrMsg = "The data could not be uncompressed"
            End Select
            If ISTAT > 10 Then Throw New IO.InvalidDataException(ErrMsg & ": " & Trim(CPath) & "; operation aborted.")

            ReDim mDate_Time(lngNSize - 1)

            StartDate = System.DateTime.FromOADate(MyCDate(VB.Left(strCDate.Value, 2) & " " & Mid(strCDate.Value, 3, 3) & " " & Mid(strCDate.Value, 6)).ToOADate + lngIOFSET / 60 / 24)
            Increment = CPath.Split("/")(PartE)
            If VB.Right(Increment, 3) = "MIN" Then
                TimeIncrement = Val(VB.Left(Increment, Len(Increment) - 3)) / 60 / 24
            ElseIf VB.Right(Increment, 4) = "HOUR" Then
                TimeIncrement = Val(VB.Left(Increment, Len(Increment) - 4)) / 24
            ElseIf VB.Right(Increment, 3) = "DAY" Then
                TimeIncrement = Val(VB.Left(Increment, Len(Increment) - 3))
            ElseIf VB.Right(Increment, 4) = "WEEK" Then
                TimeIncrement = Val(VB.Left(Increment, Len(Increment) - 4)) * 7
            ElseIf VB.Right(Increment, 3) = "MON" Then
                TimeIncrement = Val(VB.Left(Increment, Len(Increment) - 3)) * 30 'not exactly correct
            ElseIf VB.Right(Increment, 4) = "YEAR" Then
                TimeIncrement = Val(VB.Left(Increment, Len(Increment) - 4)) * 365 'not exactly correct
            Else
                Throw New IO.InvalidDataException("Invalid time interval: " & Increment)
            End If

            For i = 0 To lngNVals - 1
                mDate_Time(i) = RoundDateTime(System.DateTime.FromOADate(StartDate.ToOADate + System.DateTime.FromOADate(i * TimeIncrement).ToOADate))
            Next i

            mUnits = strCUnits.Value
        End If

        If NotRTS Then Throw New IO.InvalidDataException("The selected data path does not contain Regular Time Series data.")
        '   Close the DSS File
        ZCLOSE(IFLTAB(1))
        lngStatus = FORTRANCLOSEFILE(10)

    End Sub

    Private Function getCatalog() As Boolean
        Dim CName, MessageFile As String
        Dim ISTAT As Integer

        Dim IFLTAB(600) As Integer

        CName = mFilename

        MessageFile = CName & ".msg"
        ISTAT = FORTRANOPENFILE(MessageFile, Len(MessageFile), 10)
        ZSET("MUNIT", 5, " ", 1, 10)

        ZOPEN(IFLTAB(1), CName, Len(CName), ISTAT)


        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        '   Open the Catalog
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        Dim strCDSSFI As New VB6.FixedLengthString(132)
        Dim lngICUNIT, lngLGENCA As Integer
        Dim lngLCATLG, lngLOPNCA, lngICDUNT As Integer
        Dim lngLOPNCD, lngLGENCD, lngLCDCAT As Integer
        Dim lngNRECS As Integer
        Dim lngL_CDSSFI As Integer

        strCDSSFI.Value = CName
        lngL_CDSSFI = Len(Trim(strCDSSFI.Value))
        lngICUNIT = 12
        lngLGENCA = CInt(True)
        '
        '   Do not generate a condensed catalog
        lngICDUNT = 0 ' 13
        lngLGENCD = 0 ' CLng(True)

        ZOPNCA(strCDSSFI.Value, lngL_CDSSFI, lngICUNIT, lngLGENCA, lngLOPNCA, lngLCATLG, lngICDUNT, lngLGENCD, lngLOPNCD, lngLCDCAT, lngNRECS)

        If lngLOPNCA <> -1 Then
            Throw New IO.FileLoadException("Unable to open catalog: " & CName & "; operation aborted.")
            Return False
        End If

        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        '   Generate the Catalog
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        Dim lngINUNIT As Integer
        Dim strCINSTR As New VB6.FixedLengthString(120)
        Dim lngL_CINSTR As Integer
        Dim lngLABREV As Integer
        Dim lngLDOSRT As Integer

        lngINUNIT = 0
        strCINSTR.Value = " "
        lngL_CINSTR = Len(strCINSTR.Value)
        lngLABREV = CInt(True)
        lngLDOSRT = CInt(True)

        ZCAT(IFLTAB(1), lngICUNIT, lngICDUNT, lngINUNIT, strCINSTR.Value, lngL_CINSTR, lngLABREV, lngLDOSRT, lngLCDCAT, lngNRECS)
        '
        '   Close the files
        Dim lngStatus As Integer
        '
        '   Close catalog file
        lngStatus = FORTRANCLOSEFILE(lngICUNIT)
        '
        '   Close condensed catalog file
        If lngLOPNCD Then lngStatus = FORTRANCLOSEFILE(lngICDUNT)

        '   Close the DSS File
        ZCLOSE(IFLTAB(1))
        lngStatus = FORTRANCLOSEFILE(10)

    End Function

    ''' <summary>
    ''' Instantiate clsData, assign filename, open file, set filelength and fieldnames
    ''' </summary>
    ''' <param name="_Filename">Name of text file to read</param>
    Public Overrides Sub Initialize(ByVal _Filename As String)
        MyBase.Initialize(_Filename)
        mDataType = enumDataType.DSS

        getCatalog()

        Dim sr As IO.StreamReader = Nothing

        Try
            Application.UseWaitCursor = True
            sr = New IO.StreamReader(IO.Path.ChangeExtension(mFilename, ".DSC"))
            Dim s As String
            Do
                s = sr.ReadLine
                If s <> "" Then mDescription &= s
            Loop Until s.StartsWith(" Number")
            sr.ReadLine()

            While Not sr.EndOfStream
                s = sr.ReadLine
                mTableNames.Add(s.Substring(18))
            End While

            mFieldNames.Clear()
            mFieldNames.Add("Date_Time")
            mFieldNames.Add("Result")

        Catch ex As Exception
            Throw
        Finally
            If sr IsNot Nothing Then
                sr.Close()
                sr = Nothing
            End If
            Application.UseWaitCursor = False
        End Try
    End Sub

    ''' <summary>
    ''' Read next line from file into memory, storing into mItems array
    ''' Also save mLastLineRead for error reporting
    ''' </summary>
    ''' <returns>True if successful, false if eof reached and no more data</returns>
    Public Overrides Function Read() As Boolean
        Try
            Do
                If Not MyBase.Read() Then Return False
                If mRecordNum > mResult.Length - 1 Then Return False
                mItems.Clear()
                mItems.Add(mDate_Time(mRecordNum).ToString(MyDateTimeFormat))
                mItems.Add(mResult(mRecordNum))
            Loop Until mResult(mRecordNum) > -900
            Return True
        Catch ex As Exception
            ErrorMsg(, ex)
            Return False
        End Try
    End Function

    ''' <summary>
    ''' Get data table containing time series data for a specified station id and pcode
    ''' Table will contain date-time field and result field
    ''' </summary>
    Public Overrides Function GetDataTable(ByVal StationID As String, ByVal PCode As String) As DataTable
        Dim dt As DataTable = MyBase.SetupDataTable(enumDataTableColumns.Date_Result)
        While Read()
            dt.Rows.Add(mItems(0), mItems(1))
        End While
        Return dt
    End Function

    Public Overrides Property ActiveTable() As String
        Get
            Return MyBase.ActiveTable
        End Get
        Set(ByVal value As String)
            'export this sheet and open it
            MyBase.ActiveTable = value
            getData(value)

            mStationIDs.Clear()
            mStationIDs.Add(ActiveTable.Split("/")(PartB))
            mPCodes.Clear()
            mPCodes.Add(ActiveTable.Split("/")(PartC))
            mMinDate = mDate_Time(0)
            mMaxDate = mDate_Time(mDate_Time.Length - 1)
        End Set
    End Property

    ''' <summary>
    ''' Determine percent of file that has been read
    ''' </summary>
    ''' <returns>Percent of file read</returns>
    Public Overrides Function PercentComplete() As Double
        Return mRecordNum * 100.0 / (mResult.Length - 1)
    End Function

End Class

Module modDSS
    Declare Function FORTRANCLOSEFILE Lib "heclib50.dll" Alias "FORTRANCLOSE_" (ByRef lngUnit As Integer) As Integer

    Declare Function FORTRANOPENFILE Lib "heclib50.dll" Alias "FORTRANOPEN_" (ByVal CName As String, ByVal L_CName As Integer, ByRef IUNIT As Integer) As Integer

    Declare Sub ZCAT Lib "heclib50.dll" Alias "ZCAT_" (ByRef lngIFLTAB As Integer, ByRef lngICUNIT As Integer, ByRef lngICDUNT As Integer, ByRef lngINUNIT As Integer, ByVal strCINSTR As String, ByVal lngL_CINSTR As Integer, ByRef lngLABREV As Integer, ByRef lngLDOSRT As Integer, ByRef lngLCDCAT As Integer, ByRef lngNORECS As Integer)

    Declare Sub ZCLOSE Lib "heclib50.dll" Alias "ZCLOSE_" (ByRef IFLTAB As Integer)

    Declare Sub ZDTYPE Lib "heclib50.dll" Alias "ZDTYPE_" (ByRef lngIFLTAB As Integer, ByVal strPath As String, ByVal lngL_Path As Integer, ByRef lngNSize As Integer, ByRef lngLExist As Integer, ByVal strDType As String, ByVal lngL_DType As Integer, ByRef lngDType As Integer)

    Declare Sub ZOPEN Lib "heclib50.dll" Alias "ZOPEN_" (ByRef IFLTAB As Integer, ByVal CName As String, ByVal Len_CName As Integer, ByRef ISTAT As Integer)

    Declare Sub ZOPNCA Lib "heclib50.dll" Alias "ZOPNCA_" (ByVal strCDSSFI As String, ByVal lngL_CDSSFI As Integer, ByRef lngICUNIT As Integer, ByRef lngLGENCA As Integer, ByRef lngLOPNCA As Integer, ByRef lngLCATLG As Integer, ByRef lngICDUNT As Integer, ByRef lngLGENCD As Integer, ByRef lngLOPNCD As Integer, ByRef lngLCATCD As Integer, ByRef lngNRECS As Integer)

    Declare Sub ZRPD Lib "heclib50.dll" Alias "ZRPD_" (ByRef lngIFLTAB As Integer, ByVal strPath As String, ByVal lngL_Path As Integer, ByRef lngNORD As Integer, ByRef lngNCURVE As Integer, ByRef lngHoriz As Integer, ByVal str1Unit As String, ByVal lngL_1Unit As Integer, ByVal str1Type As String, ByVal lngL_1Type As Integer, ByVal str2Unit As String, ByVal lngL_2Unit As Integer, ByVal str2Type As String, ByVal lngL_2Type As Integer, ByRef sngValues As Single, ByRef lngKVals As Integer, ByRef lngNVals As Integer, ByVal strLabel As String, ByVal lngL_Label As Integer, ByRef lngKLabel As Integer, ByRef lngLabel As Integer, ByRef lngHEADU As Integer, ByRef lngHKeadU As Integer, ByRef lngNHEADU As Integer, ByRef lngSTAT As Integer)

    Declare Sub ZRRTS Lib "heclib50.dll" Alias "ZRRTS_" (ByRef lngIFLTAB As Integer, ByVal strCPATH As String, ByVal lngL_CPath As Integer, ByVal strCDate As String, ByVal lngL_CDate As Integer, ByVal strCTime As String, ByVal lngL_CTime As Integer, ByRef lngNVals As Integer, ByRef sngValues As Single, ByVal strCUnits As String, ByVal lngL_CUnits As Integer, ByVal strCType As String, ByVal lngL_CType As Integer, ByRef lngIOFSET As Integer, ByRef lngISTAT As Integer)

    Public Declare Sub ZSET Lib "heclib50.dll" Alias "ZSET_" (ByVal strSet As String, ByVal lngL_Set As Integer, ByVal strVal As String, ByVal lngL_Val As Integer, ByRef lngVal As Integer)

    Declare Sub ZSPD Lib "heclib50.dll" Alias "ZSPD_" (ByRef lngIFLTAB As Integer, ByVal strPath As String, ByVal lngL_Path As Integer, ByRef lngNORD As Integer, ByRef lngNCURVE As Integer, ByRef lngHoriz As Integer, ByVal str1Unit As String, ByVal lngL_1Unit As Integer, ByVal str1Type As String, ByVal lngL_1Type As Integer, ByVal str2Unit As String, ByVal lngL_2Unit As Integer, ByVal str2Type As String, ByVal lngL_2Type As Integer, ByRef sngValues As Single, ByVal strLabel As String, ByVal lngL_Label As Integer, ByRef lngLabel As Integer, ByRef lngHEADU As Integer, ByRef lngNHEADU As Integer, ByRef lngPlan As Integer, ByRef lngSTAT As Integer)

    Declare Sub ZSRTS Lib "heclib50.dll" Alias "ZSRTS_" (ByRef lngIFLTAB As Integer, ByVal strCPATH As String, ByVal lngL_CPath As Integer, ByVal strCDate As String, ByVal lngL_CDate As Integer, ByVal strCTime As String, ByVal lngL_CTime As Integer, ByRef lngNVals As Integer, ByRef sngValues As Single, ByVal strCUnits As String, ByVal lngL_CUnits As Integer, ByVal strCType As String, ByVal lngL_CType As Integer, ByRef lngIPLAN As Integer, ByRef lngISTAT As Integer)
    '
    '   Routine that computes the axis labeling for a date axis
    Declare Sub DETTAXIS Lib "heclib50.dll" (ByRef JULS As Integer, ByRef ISTIME As Integer, ByRef JULE As Integer, ByRef IETIME As Integer, ByRef JMinTic As Integer, ByRef ITMinTic As Integer, ByRef NMinTic As Integer, ByRef JMAJTIC As Integer, ByRef ITMAJTIC As Integer, ByRef NMAJTIC As Integer, ByRef J2AXIS As Integer, ByRef IT2AXIS As Integer, ByRef NC2AXISL As Integer, ByVal CoLMAJTIC As String, ByVal L_CoLMAJTIC As Integer, ByVal C2oAXISL As String, ByVal L_C2oAXISL As Integer, ByRef ISTAT As Integer)
End Module